
export class VoiceCodeHelper {

    private static radix = 12;
    private static base: number
    private static encodermap = {}
    private static decodermap = {}

    public static init() {
        this.base = 128 - this.radix
        for (var i = 0; i < 256; ++i) {
            var code = null;
            var v = i + 1;
            if (v >= this.base) {
                code = this.crypto(v);
            }
            else {
                code = String.fromCharCode(v);
            }
            this.encodermap[i] = code;
            this.decodermap[code] = i;
        }
    }

    private static crypto(value) {
        value -= this.base;
        var h = Math.floor(value / this.radix) + this.base;
        var l = value % this.radix + this.base;
        return String.fromCharCode(h) + String.fromCharCode(l);
    }

    public static getCode(content, index) {
        var c = content.charCodeAt(index);
        if (c >= this.base) {
            c = content.charAt(index) + content.charAt(index + 1);
        }
        else {
            c = content.charAt(index);
        }
        return c;
    }

    public static encode(data) {
        var content = "";
        var len = data.length;
        var a = (len >> 24) & 0xff;
        var b = (len >> 16) & 0xff;
        var c = (len >> 8) & 0xff;
        var d = len & 0xff;
        content += this.encodermap[a];
        content += this.encodermap[b];
        content += this.encodermap[c];
        content += this.encodermap[d];
        for (var i = 0; i < data.length; ++i) {
            content += this.encodermap[data[i]];
        }
        return content;
    }

    public static decode(content) {
        var index = 0;
        var len = 0;
        for (var i = 0; i < 4; ++i) {
            var c = this.getCode(content, index);
            index += c.length;
            var v = this.decodermap[c];
            len |= v << (3 - i) * 8;
        }

        var newData = new Uint8Array(len);
        var cnt = 0;
        while (index < content.length) {
            var c = this.getCode(content, index);
            index += c.length;
            newData[cnt] = this.decodermap[c];
            cnt++;
        }
        return newData;
    }

}